package com.cgs.query.remote.netty

import io.netty.buffer.*
import java.net.SocketAddress

/**
 * netty服务端管理
 */
interface INettyServerManager {
    /**
     * 注册netty服务端
     */
    fun registryNettyServer(server: String, nettyServer: NettyServer)

    /**
     * 获取所有netty服务端的基本信息
     */
    fun getAllNettyServerInfo(): List<NettyServerInfo>

    /**
     * 获取某个服务端的日志信息
     */
    fun getNettyServerLog(server: String): List<NettyServerLog>?
}

/**
 * 基础的信息
 */
class SimpleNettyServerManager : INettyServerManager {

    private val nettyServerHolder = mutableMapOf<String, NettyServer>()

    override fun registryNettyServer(server: String, nettyServer: NettyServer) {
        nettyServerHolder[server] = nettyServer
    }

    override fun getAllNettyServerInfo(): List<NettyServerInfo> {
        return nettyServerHolder.map {
            NettyServerInfo(it.key, it.value.channelGroup.map { channel ->
                mapOf<String, Any>("remoteAddress" to channel.remoteAddress(),
                        "metrics" to getAllocatorMetricInfo(channel.alloc()),
                        "appName" to (it.value.channelId2AppName[channel.id()] ?: "unknown")
                )
            })
        }
    }

    override fun getNettyServerLog(server: String): List<NettyServerLog>? {
        return nettyServerHolder[server]?.channelActiveLogQueue?.toList()
    }

    private fun getAllocatorMetricInfo(byteBufAllocator: ByteBufAllocator): Map<String, Any> {

        return when (byteBufAllocator) {
            is PooledByteBufAllocator -> {
                val metric: PooledByteBufAllocatorMetric = byteBufAllocator.metric()
                mapOf(
                        "usedHeapMemory" to metric.usedHeapMemory(),
                        "usedDirectMemory" to metric.usedDirectMemory(),
                        "numHeapArenas" to metric.numHeapArenas(),
                        "numDirectArenas" to metric.numDirectArenas(),
                        "tinyCacheSize" to metric.tinyCacheSize(),
                        "smallCacheSize" to metric.smallCacheSize(),
                        "normalCacheSize" to metric.normalCacheSize(),
                        "numThreadLocalCaches" to metric.numThreadLocalCaches(),
                        "chunkSize" to metric.chunkSize()
                )
            }
            is UnpooledByteBufAllocator -> {
                val metric = byteBufAllocator.metric()
                mapOf("usedDirectMemory" to metric.usedDirectMemory(),
                        "usedHeapMemory" to metric.usedHeapMemory()
                )
            }
            else -> {
                mapOf()
            }
        }
    }
}

/**
 * netty信息类
 */
data class NettyServerInfo(
        /**端口号*/
        val port: String,
        /**已连接的客户端*/
        val connectClientInfo: List<Map<String, Any>>)
